package kisti.lod.classification;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import kisti.lod.classification.db.DBConnector;
import kisti.lod.classification.db.Domain;
import kisti.lod.classification.group.Group;
import kisti.lod.classification.group.Groups;

import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.tdb.TDBFactory;
import com.j256.ormlite.dao.CloseableIterator;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;

/**
 * Iterates over all groups, counts the number of URIs in the groups
 * and outputs the result in a comma seperated list 
 * @author Sebastian
 */
public class GroupFrequency {
	
	public static void main (String[] args) throws IOException, SQLException {
		//prepare csv file
		
		Logger logger = Logger.getLogger(GroupFrequency.class);
		
		StringBuffer frequencies = new StringBuffer();
		frequencies.append("PredicateGroup, Count\n");
		
		//create groups
		Groups groups = new Groups();
		
		// iterate over domains and their respective triplestores
	 	Dao<Domain, String> domainDao = DaoManager.createDao(
	 			DBConnector.getConnectionSource(), Domain.class);
	 	CloseableIterator<Domain> domainIterator = domainDao.iterator();
	 	while (domainIterator.hasNext()) {
	 		
	 		String domain = domainIterator.next().getName();
			//create jena model
			Dataset ds = TDBFactory.createDataset(FileFactory.getTdbDomainFolder(domain));
		    Model model = ds.getDefaultModel();
		
		 	//iterate over groups
			Iterator<Entry<String, kisti.lod.classification.group.Group>> it = groups.getGroups().entrySet().iterator();
			while(it.hasNext()) {
				String query = "SELECT (COUNT(*) AS ?count)" +
						"WHERE { \n %s }";
				Entry<String, Group> entry = it.next();
				Group group = entry.getValue();
	
				//iterate over all uris in group
				ArrayList<String> predicates = group.getPredicates();
				boolean first = true;
				StringBuffer where = new StringBuffer();
				for(String predicate : predicates) {
					String union = " UNION";
					if(first) {
						union = "";
						first = false;
					}
					where.append(union + "{?s <" + predicate + "> ?o} \n");
				}
				
				query = String.format(query, where);
				Query sparqlQuery = QueryFactory.create(query);
				QueryExecution quexec = QueryExecutionFactory.create(sparqlQuery, model);
				
				ResultSet results = quexec.execSelect();
				System.out.println(query);
				if(results.hasNext()) {
					QuerySolution soln = results.nextSolution();
					int count = soln.getLiteral("count").getInt();
	//				Literal l = soln.getLiteral("count");
	//				System.out.println(l.getInt());
					frequencies.append(group.getGroupName() + "," + count + "\n");
				}
				else {
					logger.warn("No triples found for group " + group.getGroupName());
					logger.warn("Used query: \n " + query);
				}
			}
		
			//save frequencies to local csv file
			File csv = FileFactory.getGroupFrequenciesFile(domain);
			BufferedWriter csvWriter = new BufferedWriter(new FileWriter(csv, true));
			csvWriter.append(frequencies.toString());
			csvWriter.close();
	 	}
	}
}